home *** CD-ROM | disk | FTP | other *** search
- /*
- InstallWedge, RemoveWedge and GetJumpTable were taken from
- UnixDirsII (by Martin W. Scott, mws@castle.ed.ac.uk)
- They are based on a method used in ISpy, a CBM-provided AmigaMail example.
- */
-
- #include <dos.h>
- #include <signal.h>
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <exec/semaphores.h>
- #include <string.h>
- #include <proto/exec.h>
-
- /* The name this JumpTable/Semaphore will get. */
- UBYTE *JTName = "AVWM-WindowMonitor-JT";
-
- #include "wbwm.h"
- #include "jumptable.h"
-
- extern struct LVOTable LVOArray[NUMBEROFFUNCTIONS];
-
- BOOL
- InstallWedge (VOID)
- {
- struct JumpTable *jumptable;
- ULONG *addressptr;
- UCOUNT i, j;
-
- Forbid ();
-
- /* Get pointer to JumpTable. Create it if necessary */
- if (jumptable = GetJumpTable (JTName))
- {
- /* Try to get exclusive lock on semaphore, in case it already existed. */
- if (AttemptSemaphore ((struct SignalSemaphore *) jumptable))
- {
- /* Make sure nobody else has function addresses in the jumptable */
- if (jumptable->jt_Owner == NULL)
- {
- jumptable->jt_Owner = FindTask (0);
- /* Don't want to disable any longer than necessary */
- Disable ();
-
- for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
- {
- /* Replace addresses in the jumptable with my own. */
- addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
- (*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
- *addressptr = (ULONG) LVOArray[j].lt_newFunction;
- }
- Enable ();
- }
- else
- printf ("Already running.\n");
- ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
- }
- else
- printf ("Can't lock table.\n");
- }
- else
- printf ("Can't create jumptable\n");
- Permit ();
-
- return ((BOOL) jumptable);
- }
-
- BOOL
- RemoveWedge (VOID)
- {
- struct JumpTable *jumptable;
- ULONG *addressptr;
- UCOUNT i, j;
-
- Forbid ();
-
- if (jumptable = GetJumpTable (JTName))
- {
- /* Check if this task owns this jumptable */
- if (jumptable->jt_Owner == FindTask (0))
- {
- /* Get the semaphore exclusively.
- * Depending on what got SetFunction ()'ed this could take some time.
- * Also note that shared locks are used to indicate the code is
- * being executed and that shared locks can jump ahead of queue'ed
- * exclusive locks, adding to the waittime.
- */
- ObtainSemaphore ((struct SignalSemaphore *) jumptable);
-
- Disable ();
-
- /* Restore old pointers in jumptable */
-
- for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
- {
- addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
- *addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
- }
- Enable ();
-
- jumptable->jt_Owner = NULL;
- ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
- }
- }
- Permit ();
-
- return (TRUE);
- }
-
- struct JumpTable *
- GetJumpTable (UBYTE * name)
- {
- struct JumpTable *jumptable;
- ULONG *addressptr;
- UWORD *jmpinstr;
- UBYTE *jtname;
- UCOUNT i, j;
-
- /* Not really necessary to forbid again, just to indicate that I don't
- * want another task to create the semaphore while I'm trying to do the
- * same. Here GetJumpTable () is only called from InstallWedge (), so it
- * will just bump the forbid count.
- */
- Forbid ();
-
- if (!(jumptable = (struct JumpTable *) FindSemaphore (name)))
- {
- if (jumptable = AllocMem (sizeof (struct JumpTable), MEMF_PUBLIC | MEMF_CLEAR))
- {
- if (jtname = AllocMem (strlen (name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
- {
- for (i = 0, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
- {
- jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
- *jmpinstr = 0x4EF9;
-
- addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
- *addressptr = (ULONG) SetFunction (
- (struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
- LVOArray[j].lt_LVO,
- (VOID *) ((UBYTE *) jumptable->jt_Function + i)
- );
- }
- jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
-
- strcpy (jtname, name);
- jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
- AddSemaphore ((struct SignalSemaphore *) jumptable);
- }
- else {
- FreeMem (jumptable, sizeof (struct JumpTable));
- jumptable = NULL;
- }
- }
- }
- Permit ();
-
- /* If succeeded, you now have a jumptable which entries point to the original
- * library functions. If another task SetFunction ()'ed one or more of those
- * already, that task can never go away anymore.
- */
- return (jumptable);
- }
-